扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
很简单, 还有些不太完善, 只支持一位整数.
在http://www.ideawu.net/person/compilersrc/stack_cal.cpp.html
1 /*******************************************
2 * file: stack_cal.cpp
3 * author: ideawu
4 * date: 2006-11-17
5 *******************************************/
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 typedef enum{
12 Token_Error = 0,
13 Token_Int = 'i',
14 Token_Div = '/',
15 Token_Mul = '*',
16 Token_Sub = '-',
17 Token_Add = '+',
18 Token_Mod = '%',
19 Token_Lp = '(',
20 Token_Rp = ')'
21 }TokenType;
22
23 class Token{
24 public:
25 int type;
26 double value;
27
28 Token(){
29 type = Token_Error;
30 value = 0;
31 }
32 };
33
34 class ArrayStack{
35 private:
36 char * name;
37 Token *tokens;
38 int size;
39 int capacity;
40
41 public:
42 ArrayStack(char* n){
43 name = n;
44 size = 0;
45 capacity = 256;
46 tokens = new Token[capacity];
47 }
48
49 ~ArrayStack(){
50 delete[] tokens;
51 }
52
53 int getSize(){
54 return size;
55 }
56
57 bool isEmpty(){
58 return (size == 0);
59 }
60
61 bool isFull(){
62 return (size == capacity);
63 }
64
65 void push(Token token){
66 if(size < capacity){
67 tokens[size ++] = token;
68 }else{
69 }
70 }
71
72 Token* pop(){
73 if(size > 0){
74 size --;
75 return &tokens[size];
76 }else{
77 return NULL;
78 }
79 }
80
81 Token* peek(){
82 if(size > 0){
83 return &tokens[size-1];
84 }else{
85 return NULL;
86 }
87 }
88
89 void toString(){
90 if(size == 0){
91 printf("%s[0]=\n", name);
92 return;
93 }
94 printf("%s[%d]=", name, size);
95 printf("(");
96 printf("{%c,%.4f}", tokens[0].type, tokens[0].value);
97 for(int i=1; i<size; i++){
98 printf(", {%c,%.4f}", tokens[i].type, tokens[i].value);
99 }
100 printf(")\n");
101 }
102 };
103
104 /*
105 * 归约函数, 从操作数栈和操作符栈各弹出一个元素,
106 * 与操作数栈顶的元素(并未弹出)运算后, 结果存在操作栈顶的元素中.
107 */
108 void calculate(ArrayStack &operandStack, ArrayStack &operatorStack){
109 if(operandStack.getSize() < 2){
110 return;
111 }
112 Token *t1 = operandStack.pop();
113 Token *t2 = operandStack.peek();
114 Token *op = operatorStack.pop();
115 switch(op->type){
116 case '*':
117 t2->value *= t1->value;
118 break;
119 case '/':
120 t2->value /= t1->value;
121 break;
122 case '+':
123 t2->value += t1->value;
124 break;
125 case '-':
126 t2->value -= t1->value;
127 break;
128 default:
129 printf("*********Syntax Error!*********\n");
130 exit(1);
131 break;
132 }
133 }
134
135
136 int main(int argc, char *argv[]){
137 char buffer[256];
138 if(argc > 1){
139 strcpy(buffer, argv[1]);
140 }else{
141 printf("Input the statement(1-256 characters):\n");
142 scanf("%s", buffer);
143 }
144
145 ArrayStack operandStack("operandStack ");
146 ArrayStack operatorStack("operatorStack");
147 int streamLen = strlen(buffer);
148 char c;
149 /*
150 * 需要归约的情况:
151 * 1. 当前的token是整数, 且操作符栈顶元素为'*'或'/';
152 * 2. 当前的token是')';
153 * 3. 当前的token是'+'或'-', 且操作符栈顶元素为'+'或'-';
154 */
155 for(int index=0; index<streamLen; index++){
156 c = buffer[index];
157 Token t;
158 if(c >= '0' && c <= '9'){
159 t.type = Token_Int;
160 t.value = c - '0';
161 operandStack.push(t);
162 if(!operatorStack.isEmpty()){
163 if(operatorStack.peek()->type == '*'
164 || operatorStack.peek()->type == '/'){
165 calculate(operandStack, operatorStack);
166 }
167 }
168 }else{
169 t.type = c;
170 Token *temp;
171 switch(c){
172 case ')':
173 if(operatorStack.isEmpty()){
174 printf("*********Syntax Error!*********\n");
175 exit(0);
176 }
177 temp = operatorStack.peek();
178 if(temp->type == '('){
179 // 使(int) ==> int, 即去掉整数两边的括号后再归约.
180 operatorStack.pop();
181 calculate(operandStack, operatorStack);
182 }else{
183 calculate(operandStack, operatorStack);
184 operatorStack.pop();
185 }
186 break;
187 case '-':
188 case '+':
189 if(!operatorStack.isEmpty()){
190 temp = operatorStack.peek();
191 if(temp->type == '+' || temp->type == '-'){
192 calculate(operandStack, operatorStack);
193 }
194 }
195 operatorStack.push(t);
196 break;
197 default:
198 operatorStack.push(t);
199 break;
200 }
201 }
202 }
203 calculate(operandStack, operatorStack);
204
205 printf("=%f", operandStack.pop()->value);
206 printf("\n");
207 return 0;
208 }
209
婵犵數濮烽弫鍛婃叏閻戝鈧倹绂掔€n亞鍔﹀銈嗗坊閸嬫捇鏌涢悢閿嬪仴闁糕斁鍋撳銈嗗坊閸嬫挾绱撳鍜冭含妤犵偛鍟灒閻犲洩灏欑粣鐐烘⒑瑜版帒浜伴柛鎾寸洴閹儳煤椤忓應鎷洪梻鍌氱墛閸楁洟宕奸妷銉ф煣濠电姴锕ょ€氼參宕h箛鏃傜瘈濠电姴鍊绘晶娑㈡煕鐎c劌濡介柕鍥у瀵粙濡歌閳ь剚甯¢弻鐔兼寠婢跺﹥娈婚梺鍝勭灱閸犳牠骞冨⿰鍫濈厸闁稿本绋撹ぐ瀣煟鎼淬値娼愭繛鍙壝悾婵堢矙鐠恒劍娈鹃梺鍓插亝濞叉牠鎮″☉銏$厱閻忕偛澧介惌瀣箾閸喐鍊愭慨濠勭帛閹峰懐绮电€n亝鐣伴梻浣规偠閸斿宕¢崘鑼殾闁靛繈鍊曢崘鈧銈嗗姂閸庡崬鐨梻鍌欑劍鐎笛呯矙閹寸姭鍋撳鐓庡籍鐎规洑鍗冲畷鍗炍熼梹鎰泿闂備線娼ч悧鍡涘箠鎼淬垺鍙忔い鎺嗗亾闁宠鍨块崺銉╁幢濡炲墽鍑规繝鐢靛О閸ㄦ椽鏁嬮柧鑽ゅ仦娣囧﹪濡堕崨顔兼闂佺ǹ顑呴崐鍦崲濞戙垹骞㈡俊顖濐嚙绾板秹鏌f惔銏e妞わ妇鏁诲璇差吋閸偅顎囬梻浣告啞閹搁箖宕版惔顭戞晪闁挎繂顦介弫鍡椼€掑顒婂姛闁活厽顨嗙换娑㈠箻閺夋垹鍔伴梺绋款儐閹瑰洭寮婚敐鍛婵炲棙鍔曠壕鎶芥⒑閸濆嫭婀扮紒瀣灴閸╃偤骞嬮敃鈧婵囥亜閺囩偞鍣洪柍璇诧功缁辨捇宕掑▎鎴濆濡炪們鍔岄幊姗€骞嗗畝鍕<闁绘劙娼х粊锕傛煙閸忚偐鏆橀柛鏂跨焸閹偤宕归鐘辩盎闂佸湱鍎ら崹鐢割敂閳哄懏鍊垫慨姗嗗墻濡插綊鏌曢崶褍顏€殿喕绮欐俊姝岊槼闁革絻鍎崇槐鎾存媴缁涘娈┑鈽嗗亝缁诲牆顕f繝姘亜缁炬媽椴搁弲锝夋偡濠婂啰效闁诡喗锕㈤幊鐘活敆閸屾粣绱查梺鍝勵槸閻楀嫰宕濇惔锝囦笉闁绘劗鍎ら悡娑㈡倶閻愯泛袚闁哥姵锕㈤弻鈩冩媴閻熸澘顫掗悗瑙勬礈閸犳牠銆佸鈧幃鈺呮惞椤愩倝鎷婚梻鍌氬€峰ù鍥х暦閸偅鍙忛柟鎯板Г閳锋梻鈧箍鍎遍ˇ顖炲垂閸岀偞鐓㈡俊顖滃皑缁辨岸鏌ㄥ┑鍡╂Ц缂佲偓鐎n偁浜滈柡宥冨妿閳藉绻涢崼鐔虹煉婵﹨娅e☉鐢稿川椤斾勘鈧劕顪冮妶搴′簼婵炶尙鍠栧畷娲焵椤掍降浜滈柟鍝勬娴滈箖姊洪幐搴㈢┛濠碘€虫搐鍗遍柟鐗堟緲缁秹鏌涢锝囩畼妞ゆ挻妞藉铏圭磼濡搫顫岄悗娈垮櫘閸撴瑨鐏冮梺鍛婁緱閸犳岸宕㈤幖浣光拺闁告挻褰冩禍浠嬫煕鐎n亜顏柟顔斤耿閺佸啴宕掑☉姘箞闂佽鍑界紞鍡涘磻閸℃ɑ娅犳い鎺戝€荤壕濂告煕鐏炲墽鈽夌紒妞﹀洦鐓欓柣鐔告緲椤忣參鏌熼悡搴㈣础闁瑰弶鎸冲畷鐔兼濞戞瑦鐝¢梻鍌氬€搁崐椋庣矆娓氣偓楠炴牠顢曢妶鍌氫壕婵ê宕崢瀵糕偓瑙勬礀缂嶅﹪寮婚崱妤婂悑闁告侗鍨界槐閬嶆煟鎼达紕鐣柛搴ㄤ憾钘濆ù鍏兼綑绾捐法鈧箍鍎遍ˇ浼存偂閺囥垺鐓涢柛銉e劚婵$厧顭胯閸ㄤ即婀侀梺缁樓圭粔顕€顢旈崼鐔虹暢闂傚倷鐒︾€笛呮崲閸屾娑樜旈崨顓犲幒闂佸搫娲㈤崹娲偂閸愵亝鍠愭繝濠傜墕缁€鍫熸叏濡寧纭鹃柦鍐枛閺屾洘绻涜鐎氱兘宕戦妸鈺傗拺缂備焦锚婵洦銇勯弴銊ュ籍闁糕斂鍨藉鎾閳ユ枼鍋撻悽鍛婄叆婵犻潧妫楅埀顒傛嚀閳诲秹宕堕妸锝勭盎闂婎偄娲︾粙鎰板箟妤e啯鐓涢悘鐐靛亾缁€瀣偓瑙勬礋娴滃爼銆佸鈧幃銏$附婢跺澶�